<?php

class Product_Models_Product extends Rabbit_Db_Table_Abstract implements Product_Models_Interfaces_Product {

    protected $_name = 'product_product';

    /**
     * Convert array data to entity
     * @param array $entity
     * @return Product_Models_Entites_Product 
     */
    public function convert($entity) {
        return new Product_Models_Entities_Product($entity);
    }

    /**
     * Get product By id
     * @param int $id
     * @return Product_Models_Entites_Product
     */
    public function getById($id) {
        $row = $this->getAdapter()
                ->select()
                ->from(array('p' => $this->_name))
                ->where('p.id = ?', $id)
                ->limit(1)
                ->query()
                ->fetch();
        return (null == $row) ? null : new Product_Models_Entities_Product($row);
    }

    public function getAll() {
        try {
            $db = $this->getAdapter();
            $select = $db->select()
                    ->from(array('p' => $this->_name), '*')
                    ->joinLeft(array('c' => $this->_prefix . 'category'), 'p.category_id = c.id', array('category_name' => 'c.name'))
                    ->where('p.status <> ?', 'deleted')
                    ->order('p.created_date DESC');
            $rs = $db->query($select)->fetchAll();
            return ($rs == null) ? null : new Tomato_Model_RecordSet($rs, $this);
        } catch (Exception $ex) {
            echo $ex->getMessage();
            return null;
        }
    }

    public function find($offset, $count, $exp = null) {
        $select = $this->getAdapter()
                ->select('*')
                ->from(array('p' => $this->_name))
                ->joinLeft(array('c' => $this->_prefix . 'category'), 'p.category_id = c.id', array('category_name' => 'c.name', 'category_slug' => 'c.slug'))
                /**
                 * @since 2.0.8
                 */
                ->where('p.language = ?', $this->_lang);

        if ($exp) {
            if (isset($exp['id'])) {
                $select->where('p.id = ?', $exp['id']);
            }
            if (isset($exp['category_id'])) {
                $select->where('p.category_id = ?', $exp['category_id']);
            }
            if (isset($exp['created_user_id'])) {
                $select->where('p.created_user_id = ?', $exp['created_user_id']);
            }
            if (isset($exp['status'])) {
                $select->where('p.status = ?', $exp['status']);
            }
            if (isset($exp['keyword'])) {
                $select->where("p.name LIKE '%" . addslashes($exp['keyword']) . "%'");
            }
        }
        $rs = $select->order('p.id DESC')
                ->limit($count, $offset)
                ->query()
                ->fetchAll();

        return new Tomato_Model_RecordSet($rs, $this);
    }

    public function count($exp = null) {
        $select = $this->getAdapter()
                ->select()
                ->from(array('p' => $this->_name), array('num_products' => 'COUNT(*)'))
                /**
                 * @since 2.0.8
                 */
                ->where('p.language = ?', $this->_lang);
        if ($exp) {
            if (isset($exp['id'])) {
                $select->where('p.id = ?', $exp['id']);
            }
            if (isset($exp['category_id'])) {
                $select->where('p.category_id = ?', $exp['category_id']);
            }
            if (isset($exp['created_user_id'])) {
                $select->where('p.created_user_id = ?', $exp['created_user_id']);
            }
            if (isset($exp['status'])) {
                $select->where('p.status = ?', $exp['status']);
            }
            if (isset($exp['keyword'])) {
                $select->where("p.name LIKE '%" . addslashes($exp['keyword']) . "%'");
            }
        }
        return $select->query()->fetch()->num_products;
    }

    public function getByCategory($categoryId, $offset, $count) {
        $rs = $this->getAdapter()
                ->select()
                ->from(array('p' => $this->_name), array('id', 'name', 'slug', 'specification', 'description', 'demo_url', 'attachment', 'image_thumbnail', 'image_small', 'image_crop', 'image_large', 'image_original', 'created_date', 'modified_date', 'created_user_name', 'category_id', 'num_views', 'num_download'))
                //->joinInner(array('ac' => $this->_prefix . 'news_article_category_assoc'), 'a.article_id = ac.article_id', array('category_id'))
                ->joinInner(array('c' => $this->_prefix . 'category'), 'p.category_id = c.id', array('category_name' => 'name', 'category_slug' => 'slug'))
                ->where('p.category_id = ? OR c.parent_id = ?', $categoryId, $categoryId)
                ->where('p.status = ?', 'actived')
                ->order('p.created_date DESC')
                ->limit($count, $offset)
                ->query()
                ->fetchAll();
        return new Tomato_Model_RecordSet($rs, $this);
    }

    public function increaseViews($productId) {
        return $this->getAdapter()->update($this->_name, array(
                    'num_views' => new Zend_Db_Expr('num_views + 1'),
                        ), array(
                    'id = ?' => $productId,
                ));
    }

    /**
     * Update rating of article
     * @param int $id
     * @param float $rate
     */
    public function rate($id, $rate) {
        $rating = $this->getAdapter()
                        ->select()
                        ->from(array('p' => $this->_name), array('rating' => 'p.rating'))
                        ->where('id = ?', $id)
                        ->limit(1)
                        ->query()
                        ->fetch()->rating;
        if ($rating && $rating != '') {
            $rating = Zend_Json::decode($rating);
            $newRate = ($rating['avg'] * $rating['num'] + $rate) / ($rating['num'] + 1);
            $newRate = array('avg' => $newRate, 'num' => $rating['num'] + 1);
            $newRate = Zend_Json::encode($newRate);
        } else {
            $newRate = array('avg' => $rate, 'num' => 1);
            $newRate = Zend_Json::encode($newRate);
        }
        return parent::update(array('rating' => $newRate), array('id = ?' => $id));
    }

    /**
     * Add new product
     * @param Product_Models_Entities_Product $product
     * @return int $id
     */
    public function add($product) {
        try {
            $product = $this->createRow($product->getProperties());
            if ($product->save()) {
                return $product->id;
            } else {
                return false;
            }
        } catch (Exception $ex) {
            echo $ex->getMessage();
            return false;
        }
    }

    public function edit($params) {
        try {
            if ($this->update($params, 'id=' . $params['id'])) {
                return true;
            } else {
                return false;
            }
        } catch (Exception $ex) {
            echo $ex->getMessage();
            return false;
        }
    }

    public function delete($id) {
        if ($id) {
            return parent::delete('id = ' . $id);
        } else {
            return $this->delete('status = ' . $this->getAdapter()->quote('deleted'));
        }
        return 0;
    }

    public function updateStatus($id, $status) {
        $user = Zend_Auth::getInstance()->getIdentity();
        $data = array('status' => $status);
        if ($status == 'actived') {
            $data['activate_user_id'] = $user->id;
            $data['activate_user_name'] = $user->username;
            $data['activate_date'] = date('Y-m-d H:i:s');
        }
        return $this->update($data, 'id = ' . $id);
    }

    /* ========== For translation =========================================== */

    public function getTranslations($item) {
        try {
            $rs = $this->getAdapter()
                    ->select()
                    ->from(array('p' => $this->_name))
                    ->joinInner(array('tr' => $this->_prefix . 'core_translation'), 'tr.item_class = ?
						AND (tr.item_id = ? OR tr.source_item_id = ?)
						AND (tr.item_id = p.id OR tr.source_item_id = p.id)', array('tr.source_item_id'))
                    ->group('p.id')
                    ->bind(array(
                        'Product_Models_Entities_Product', //Changed by Tronghm
                        $item->id,
                        $item->id,
                    ))
                    ->query()
                    ->fetchAll();
            return (null == $rs) ? null : new Tomato_Model_RecordSet($rs, $this);
        } catch (Exception $ex) {
            echo $ex->getMessage();
            return null;
        }
    }

    public function getTranslatable($lang, $count) {
        $rs = $this->getAdapter()
                ->select()
                ->from(array('p' => $this->_name))
                ->joinLeft(array('tr' => $this->_prefix . 'core_translation'), 'tr.source_item_id = p.id
							AND tr.item_class = ?
							AND tr.language = ?', array('translatable' => '(tr.item_id IS NULL)'))
                ->where('p.language <> ?')
                ->order('p.id DESC')
                ->limit($count)
                ->bind(array(
                    $this->_lang,
                    'Product_Models_Entities_Product',
                    $lang
                ))
                ->query()
                ->fetchAll();
        return new Tomato_Model_RecordSet($rs, $this);
    }

    public function getSource($product) {
        $row = $this->getAdapter()
                ->select()
                ->from(array('p' => $this->_name))
                ->joinInner(array('tr' => $this->_prefix . 'core_translation'), 'p.id = tr.source_item_id', array())
                ->where('tr.item_class = ?', 'Product_Models_Entities_Product')
                ->where('tr.item_id = ?', $product->id)
                ->limit(1)
                ->query()
                ->fetch();
        return (null == $row) ? null : new Product_Models_Entities_Product($row);
    }

    /**
     * Check product name exists or not
     * Add by Tronghm
     * @param string $name
     * @return bool
     */
    public function exist($name) {
        $row = $this->getAdapter()
                ->select()
                ->from(array('p' => $this->_name))
                ->where('p.name = ?', $name)
                ->limit(1)
                ->query()
                ->fetch();
        return ($row != null) ? true : false;
    }

    /**
     * Get featured product
     * @author TrongHM
     * @param int $litmit
     * @return array 
     */
    public function getFeatured($params = array('category_id' => array(), 'limit' => '10')) {
        //$fearturedProduct
        try {
            $select = $this->getAdapter()->select()
                    ->from(array('p' => $this->_name))
                    ->joinLeft(array('c' => $this->_prefix . 'category'), 'p.category_id = c.id', array('category_id' => 'c.id', 'category_slug' => 'c.slug'))
                    ->where('p.featured = ?', 1)
                    ->where('status = ?', 'actived')
                    ->where('p.language = ?', $this->_lang)
                    ->limit($params['limit']);

            if (!empty($params['category_id'])) {
                if (is_array($params['category_id'])) {
                    $select->where('c.id IN (?)', implode($params['category_id'], ','));
                } else {
                    $select->where('c.id = ? ', $params['category_id']);
                }
            }
            $products = $select->query()->fetchAll();
            return (null == $products) ? null : new Tomato_Model_RecordSet($products, $this);
        } catch (Exception $ex) {
            echo $ex->getMessage();
        }
    }

    /**
     * Get relate products of a product
     * @param int $productId
     * @param type $limit 
     */
    public function getRelate($productId, $limit = 10) {
        $product = $this->getById($productId);
        if(!$product) return null;
        $rs = $this->getAdapter()->select()
                    ->from(array('p' => $this->_name))
                    ->joinLeft(array('c' => $this->_prefix . 'category'), 'p.category_id = c.id', array('category_id' => 'c.id', 'category_slug' => 'c.slug'))
                    ->where('p.category_id = ? ', $product->category_id)
                    ->where('p.language = ?', $product->language)
                    ->limit($limit)
                    ->query()->fetchAll();

        return $rs == null ? null : new Tomato_Model_RecordSet($rs, $this);
    }

}

?>
